﻿using Mozi.HttpEmbedded.Extension;
using System;
using System.Collections.Generic;

namespace Mozi.Live.RTP
{
    /// <summary>
    /// RTCP SR报文
    /// </summary>
    public class RTCPSenderPackage:AbsRTCPPackage
    {
        /// <summary>
        /// 包类型
        /// </summary>
        public override RTCPPackageType PackageType
        {
            get
            {
                return RTCPPackageType.SenderReport;
            }
            set
            {
                return;
            }
        }

        /// <summary>
        /// 源标识符 同步源|贡献源
        /// </summary>
        public uint Identifier { get; set; }
        /// <summary>
        /// 时间戳高位
        /// </summary>
        public uint SendTimeM { get; set; }
        /// <summary>
        /// 时间戳低位 
        /// </summary>
        public uint SendTimeL { get; set; }

        //TODO 这里的计算有问题
        /// <summary>
        /// 64bits 高位在前，低位在后。此处算法参考NTP协议中的时间戳的计算方式
        /// </summary>
        public DateTime SendTime
        {
            get
            {
                DateTime localTime =new DateTime(1900,1,1);
                //秒的部分
                localTime =localTime.AddSeconds(SendTimeM);
                //100纳秒的部分
                localTime = localTime.AddTicks((long)((double)SendTimeL / ((ulong)1 + uint.MaxValue) * 1e7));
                return localTime;
            }
            set
            {
                DateTime dateTimeStart = new DateTime(1900, 1, 1);
                var dtDiff = (value - dateTimeStart);
                SendTimeM = (uint)dtDiff.TotalSeconds;
                SendTimeL = (uint)(((double)(dtDiff.Ticks / 1e7) - SendTimeM) * 1e7 * ((ulong)1 + uint.MaxValue));
            }
        }
        /// <summary>
        /// 时间戳
        /// </summary>
        public uint Timestamp { get; set; }
        /// <summary>
        /// 已发送的包的数量
        /// </summary>
        public uint PacketCount { get; set; }
        /// <summary>
        /// 已发送的荷载字节数，仅统计RTP的Payload部分，不包含头和填充数据
        /// </summary>
        public uint PayloadLength { get; set; }
        public List<RTCPReportBlock> Reports { get; set; }
        public byte[] Extension { get; set; }
        /// <summary>
        /// 打包数据
        /// </summary>
        /// <returns></returns>
        public override byte[] Pack()
        {
            List<byte> buffer = new List<byte>();
            buffer.AddRange(PackHeader());
            buffer.AddRange(Identifier.ToBigEndian());
            buffer.AddRange(SendTimeM.ToBigEndian());
            buffer.AddRange(SendTimeL.ToBigEndian());
            buffer.AddRange(Timestamp.ToBigEndian());
            buffer.AddRange(PacketCount.ToBigEndian());
            buffer.AddRange(PayloadLength.ToBigEndian());
            if (Reports != null)
            {
                foreach(var r in Reports)
                {
                    buffer.AddRange(r.Pack());
                }
            }
            if (Extension != null)
            {
                buffer.AddRange(Extension);
            }
            //最后计算长度
            byte[] data = buffer.ToArray();
            Length = (ushort)(data.Length / 4 - 1);
            Array.Copy(Length.ToBigEndian(), 0, data, 2, 2);
            return data;
        }
        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static new RTCPSenderPackage Parse(byte[] data)
        {
            RTCPSenderPackage pack = new RTCPSenderPackage();
            byte[] head = new byte[4];
            Array.Copy(data, 0, head, 0, 4);
            pack.ParseHeader(head);

            pack.Identifier = data.GetBigEndianUInt32(4);
            pack.SendTimeM = data.GetBigEndianUInt32(8);
            pack.SendTimeL = data.GetBigEndianUInt32(12);
            pack.Timestamp = data.GetBigEndianUInt32(16);
            pack.PacketCount = data.GetBigEndianUInt32(20);
            pack.PayloadLength = data.GetBigEndianUInt32(24);

            pack.Reports = new List<RTCPReportBlock>();
            for (int i = 0; i < pack.ReportCount; i++)
            {
                byte[] reportData = new byte[20];
                Array.Copy(data, 28 + 20 * i, reportData, 0, 20);
                pack.Reports.Add(RTCPReportBlock.Parse(reportData));
            }
            //TODO 扩展信息暂时不管
            return pack;
        }
    }
}
